package com.pacvue.properties;

import com.pacvue.enums.RateLimiterHandlerType;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * RateLimiterProperties
 * 限流全局配置类
 */
@Data
@ConfigurationProperties(prefix = "rate-limiter")
public class RateLimiterProperties {
    /**
     * 是否启用
     */
    private boolean enabled = true;

    /**
     * 令牌桶容量, 默认1
     */
    private int capacity = 1;
    
    /**
     * 令牌桶的每秒产生的令牌数, 默认1
     */
    private double rate = 1;
    
    /**
     * 等待令牌的最大等待时间（阻塞式等待，会占用当前线程）, 默认30秒
     */
    private int timeout = 30;

    /**
     * 限流处理器类型, 默认使用LocalRateLimiterAcquireTokenHandler。
     * 如果需要使用RedisRateLimiterAcquireTokenHandler，则需要在配置文件中设置handler-type为redis。并配置spring.data.redis相关属性
     * {@link com.pacvue.enums.RateLimiterHandlerType}
     */
    private RateLimiterHandlerType handlerType = RateLimiterHandlerType.LOCAL;

    private RedisConfig redis;

    /**
     * 重试配置， 当获取到令牌后调用方法仍抛出RedisRateLimitException时，是否需要重试
     */
    private Retry retry = new Retry();

    /**
     * 本地限流器配置
     */
    private LocalConfig local = new LocalConfig();

    @Data
    public static class RedisConfig {
        private String host;

        private int port = 6379;

        private String password;

        private int database = 0;
        
        /**
         * 连接超时时间（秒）
         */
        private int connectionTimeout = 5;
        
        /**
         * 命令超时时间（秒）
         */
        private int commandTimeout = 3;
    }

    @Data
    public static class Retry {
        /**
         * 是否重试
         */
        private boolean enabled = false;
        
        /**
         * 重试次数，如果需要在令牌最大等待时间内不停重试， 则需要将此字段设置为0
         */
        private int retryTimes = 3;
    }
    
    @Data
    public static class LocalConfig {
        /**
         * 缓存清理间隔（分钟）
         */
        private int cleanupIntervalMinutes = 30;
        
        /**
         * 桶过期时间（分钟）
         */
        private int bucketExpireMinutes = 60;
    }
}
